import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.font_manager import FontProperties
import matplotlib

# 使用学术风格的字体和样式
plt.style.use('seaborn-v0_8-whitegrid')
plt.rcParams.update({
    'font.family': 'serif',
    'font.serif': ['Times New Roman', 'DejaVu Serif', 'Computer Modern Roman'],
    'mathtext.fontset': 'stix',
    'font.size': 10,
    'axes.labelsize': 11,
    'axes.titlesize': 12,
    'xtick.labelsize': 9,
    'ytick.labelsize': 9,
    'legend.fontsize': 9,
    'figure.dpi': 300
})

# 数据框架设置
data = {
    'model': ['faster-rcnn'] * 10 + ['cascade-rcnn'] * 10 + ['retinanet'] * 10 + ['detr'] * 10 + [
        'deformable detr'] * 10 + ['algaeDiff-net'] * 10,
    'category': ['Chlorella', 'Dictyosphaerium', 'Kirchneriella', 'Limnothrix', 'Merismopedia_elegans',
                 'Merismopedia_minima', 'Microcystis_robusta', 'Oocystis', 'Platymonas', 'Spirulina'] * 6,
    'mAP': [0.81, 0.791, 0.802, 0.714, 0.741, 0.765, 0.679, 0.9, 0.896, 0.752,
            0.82, 0.807, 0.801, 0.727, 0.755, 0.791, 0.681, 0.906, 0.899, 0.785,
            0.632, 0.346, 0.577, 0.053, 0.428, 0.604, 0.539, 0.669, 0.584, 0.047,
            0.775, 0.705, 0.779, 0.654, 0.586, 0.685, 0.633, 0.875, 0.88, 0.69,
            0.803, 0.758, 0.804, 0.589, 0.727, 0.759, 0.713, 0.89, 0.878, 0.618,
            0.831, 0.809, 0.821, 0.787, 0.757, 0.778, 0.731, 0.92, 0.899, 0.845]
}

df = pd.DataFrame(data)
pivot_table = df.pivot(index='model', columns='category', values='mAP')

# 计算每个模型的平均mAP
model_avg_map = pivot_table.mean(axis=1).round(3)
print("各模型平均mAP:")
for model, avg_map in model_avg_map.items():
    print(f"{model}: {avg_map}")

# 设置雷达图参数
categories = pivot_table.columns.tolist()
N = len(categories)
angles = np.linspace(0, 2 * np.pi, N, endpoint=False).tolist()
angles += angles[:1]

# 创建图形 - 使用黄金比例尺寸
fig = plt.figure(figsize=(9, 6), dpi=300)
ax = fig.add_subplot(111, polar=True)

# 定义学术风格的配色方案（适合学术出版物，色盲友好）
colors = ['#0173B2', '#DE8F05', '#029E73', '#D55E00', '#CC78BC', '#CA9161']
line_styles = ['-', '--', '-.', ':', '-', '--']
markers = ['o', 's', '^', 'D', 'v', 'p']
line_widths = [1.25] * 6

# 设置背景样式
ax.set_facecolor('#FFFFFF')
ax.grid(color='#E0E0E0', linestyle='-', linewidth=0.5, alpha=0.7)

# 绘制数据
for i, model in enumerate(pivot_table.index):
    values = pivot_table.loc[model].tolist()
    values += values[:1]

    # 格式化模型名称以符合学术论文格式（使用斜体或特定格式）
    if model == 'algaeDiff-net':
        model_label = 'AlgaeDiff-Net'
    else:
        # 将模型名称格式化为标准学术格式
        model_label = model.replace('-', '-').title()
        if model == 'detr':
            model_label = 'DETR'
        elif model == 'deformable detr':
            model_label = 'Deformable DETR'

    # 添加平均mAP到标签中
    model_label = f"{model_label} (mAP={model_avg_map[model]:.3f})"

    ax.plot(angles, values, color=colors[i], linestyle=line_styles[i],
            linewidth=line_widths[i], marker=markers[i], markersize=5,
            label=model_label, markerfacecolor='white', markeredgewidth=1.2,
            markeredgecolor=colors[i])
    ax.fill(angles, values, color=colors[i], alpha=0.1)

# 设置刻度和标签
ax.set_xticks(angles[:-1])

# 格式化物种名称为斜体
formatted_categories = []
for category in categories:
    if '_' in category:
        genus, species = category.split('_')
        formatted_categories.append(f'{genus} {species}')
    else:
        formatted_categories.append(category)

ax.set_xticklabels(formatted_categories, fontsize=9)

# 设置y轴范围和刻度
ax.set_ylim(0.1, 1)
ax.set_yticks(np.arange(0, 1.1, 0.2))
ax.set_yticklabels([f'{x:.1f}' for x in np.arange(0, 1.1, 0.2)], fontsize=8)

# 调整刻度标签位置和角度，使其更易读
# 使用更安全的方法来调整标签位置
for i, (label, angle) in enumerate(zip(ax.get_xticklabels(), angles[:-1])):
    # 根据角度决定对齐方式
    if angle < np.pi:
        label.set_horizontalalignment('left')
    else:
        label.set_horizontalalignment('right')

    # 调整角度，使标签更易读
    label.set_rotation(angle * 180 / np.pi - 90)
    label.set_fontsize(9)
    # 设置斜体
    label.set_fontstyle('italic')

    # 不要尝试手动设置位置，让matplotlib自动处理

# 特别处理 Merismopedia_elegans 标签 - 使用注释而不是移动标签
# 找到 Merismopedia_elegans 的索引
me_index = categories.index('Merismopedia_elegans')
me_angle = angles[me_index]
me_value = 1.05  # 略微超出图表边界

# 使用注释添加标签
ax.annotate('Merismopedia elegans',
            xy=(me_angle, 0.8),  # 在雷达图上的锚点
            xytext=(me_angle, me_value),  # 文本位置
            fontsize=9,
            fontstyle='italic',
            ha='center' if me_angle == np.pi / 2 or me_angle == 3 * np.pi / 2 else (
                'left' if me_angle < np.pi else 'right'),
            va='center',
            arrowprops=dict(arrowstyle='-', color='gray', lw=0.5))

# 隐藏原始的 Merismopedia_elegans 标签
ax.get_xticklabels()[me_index].set_visible(False)

# 添加图例，调整位置避免遮挡
legend = plt.legend(loc='upper center', bbox_to_anchor=(0.5, -0.12),
                    frameon=True, facecolor='white', edgecolor='#E0E0E0',
                    fontsize=9, ncol=2, columnspacing=1.0, handletextpad=0.5)

# 添加标题和副标题，符合学术论文格式
plt.title('Detection Performance Comparison Across Algae Species',
          pad=15, fontsize=12, fontweight='bold')

# 调整布局以确保所有元素可见
plt.tight_layout()

# 保存图形，使用高分辨率和无损格式
plt.savefig('./algae_detection_performance.png', dpi=300, bbox_inches='tight')

# 显示图形
# plt.show()

# 计算每个物种的平均检测难度
species_difficulty = pivot_table.mean(axis=0).sort_values()
print("\n各物种平均检测性能 (按难度排序):")
for species, score in species_difficulty.items():
    print(f"{species:<20}: {score:.3f}")
